/******************************************************
Cours:  LOG121
Projet: Squelette du laboratoire #1
Nom du fichier: CommBase.java
Date créé: 2013-05-03
*******************************************************
Historique des modifications
*******************************************************
*@author Patrice Boucher
2013-05-03 Version initiale
*******************************************************/  

import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.SwingWorker;

/**
 * Base d'une communication via un fil d'execution parallele.
 */
public class CommBase {
	
	private SwingWorker threadComm =null;
	private PropertyChangeListener listener = null;
	private boolean isActif = false;
	private Socket client = null;
	private PrintWriter output = null;
	private BufferedReader input = null;
	private CreateurFormes createurFormes = null;
	private ListeFormes liste;
	private Sorter s;
	
	//String permettant la sauvegarde des informations de connexion
	private String sauvegardeConnexion = null;
	
	/**
	 * Constructeur
	 */
	public CommBase(){
		this.createurFormes = new CreateurFormes();
		this.liste = new ListeFormes();
		this.s = new Sorter();
	}
	
	/**
	 * Accesseur des infos de connexion sauvegardees
	 */
	public String getSauvegardeConnexion() {
		return this.sauvegardeConnexion;
	}
	
	/**
	 * Definir le recepteur de l'information recue dans la communication avec le serveur
	 * @param listener sera alerte lors de l'appel de "firePropertyChanger" par le SwingWorker
	 */
	public void setPropertyChangeListener(PropertyChangeListener listener){
		this.listener = listener;
	}
	
	/**
	 * Demarre la communication et decompose la chaine contenant
	 * le nom d'hote et le numero de port. Ces informations sont sauvegardes
	 * afin de pouvoir obtenir de nouvelles formes du meme serveur sans devoir
	 * entrer les informations de connexion de nouveau
	 */
	public void start(String infos_connection){
		
		//ce que l'utilisateur a entre, dans une seule string
		sauvegardeConnexion = infos_connection;
		
		//decompose la string en prenant le : comme separateur la premiere partie est l'hote
		String host = infos_connection.substring(0, infos_connection.indexOf(':'));
		//ce qui se trouve a droite des : sera le numero de port
		String port_number = infos_connection.substring(infos_connection.indexOf(':')+1,infos_connection.length());
		
		try{
			client = new Socket(host,Integer.parseInt(port_number));
			output = new PrintWriter(client.getOutputStream(),true);
			input = new BufferedReader(new InputStreamReader(client.getInputStream()));
		}
		catch(IOException e){
			e.printStackTrace();
		}
		/*Si la liste est pleine, on en cree une nouvelle pour contenir
		 * les 10 nouvelles formes que le serveur va envoyer
		 */
		if(this.liste.getNbFormes() == 10)
			this.liste = new ListeFormes();
		// demande les 10 nouvelles formes au serveur
		creerCommunication();
	}
	
	/**
	 * Arrete la communication
	 */
	public void stop(){
		if(threadComm!=null)
			threadComm.cancel(true);
		try{
			client.close();
		}
		catch(IOException e){
			e.printStackTrace();
		}
		isActif = false;
	}
	
	public ListeFormes getListe(){
		return this.liste;
	}
	/**
	 * Cette methode est appellee par les JradioButton et
	 * tri la liste a l'aide de l'objet Sorter
	 * @param typeDeTri un int representant un tri specifique
	 */
	public void triage_liste(int typeDeTri){
		this.s.triage(this.liste,typeDeTri);
	}
	
	/**
	 * Creer le necessaire pour la communication avec le serveur
	 */
	protected void creerCommunication(){		
		// Cree un fil d'execution parallele au fil courant,
		threadComm = new SwingWorker(){
			@Override
			protected Object doInBackground() throws Exception {
				System.out.println("Le fils d'execution parallele est lance");
				int i = 0;
				// on demande 10 formes au serveur avant de les creer et de les stocker dans la liste
				while(i<10){
					
					//Clear commande>
					input.readLine();
					
					//Envoie la commande GET au serveur afin de recevoir une forme a dessiner
					output.println("GET");
					// la ligne "raw" du serveur
					String ligne = input.readLine();
					// cree la forme appropriee
					AbstractForme f = createurFormes.creerForme(ligne);
					//on ajoute la forme dans la liste
					liste.ajouterForme(f);
					
				i++;		
				}
				CommBase.this.stop();
				return null;
			}
			
		};
		if(listener!=null)
		   threadComm.addPropertyChangeListener(listener); // La méthode "propertyChange" de ApplicationFormes sera donc appelée lorsque le SwinkWorker invoquera la méthode "firePropertyChanger" 		
		threadComm.execute(); // Lance le fil d'exécution parallèle.
		isActif = true;
	}
	
	/**
	 * @return si le fil d'exécution parallèle est actif
	 */
	public boolean isActif(){
		return isActif;
	}

}
